package tms.util.localization;

import tms.business.xml.XmlBindingService;
import tms.util.constants.CookieParameter;
import tms.util.constants.UiMessage;
import tms.util.context.Config;
import tms.util.jsf.FacesContextManager;

import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.InputStream;
import java.io.Serializable;
import java.util.*;

@Named("localizer")
@SessionScoped
public class LocalizationManager implements Serializable {
    @EJB
    XmlBindingService xmlBindingService;
    @Inject
    FacesContextManager facesContextManager;

    private Map<String, Constant> constants;
    private Locale currentLocale;


    public void reloadConstants() {
        initConstants();
    }

    public String localized(String id) {
        String retVal = "";

        Constant constant = getConstants().get(id);
        if (constant != null) {
            retVal = constant.getLocalized(currentLocale);    
        }
        
        return retVal;
    }

    public String localizedMessage(UiMessage message) {
        return localized(message.name());
    }

    public List<Locale> getSupportedLocales() {
        List<Locale> retVal = new ArrayList<Locale>();
        for (Constant.SupportedLocale supportedLocale : Constant.SupportedLocale.values()) {
            retVal.add(supportedLocale.locale());
        }
        return retVal;
    }

    public void setLanguage(String code) {
        Locale locale = new Locale(code);
        currentLocale = locale;
        facesContextManager.getViewRoot().setLocale(locale);
        updateCookie(code);
    }

    public Locale getLocale() {
        if (currentLocale == null) {
            initLocale();
        }
        return currentLocale;
    }
    

    private Map<String, Constant> getConstants() {
        if (constants == null) {
            initConstants();
        }
        return constants;
    }

    synchronized private void initConstants() {
        InputStream inputStream = facesContextManager.getExternalContext().getResourceAsStream(Config.LOCALIZATION.file());
        ConstantContainer constantContainer = xmlBindingService.unmarshal(ConstantContainer.class, inputStream);
        constants = new HashMap<String, Constant>(constantContainer.getConstants().size());
        for (Constant constant : constantContainer.getConstants()) {
            constants.put(constant.getId(), constant);
        }
    }

    private void initLocale() {
        String langCookie = facesContextManager.getCookieParameter(CookieParameter.LANG);
        if (!langCookie.isEmpty()) {
            currentLocale = new Locale(langCookie);
        } else {
            currentLocale = Constant.SupportedLocale.defaultLocale();
        }
    }

    private void updateCookie(String code) {
        facesContextManager.addCookie(CookieParameter.LANG, code, 2678400);
    }
}
